!-------------------------------------------------------------LICENSE--------------------------------------------------------------!
!                                                                                                                                  !
!The MAP code is written in Fortran language for magnetohydrodynamics (MHD) calculation with the adaptive mesh refinement (AMR)    !
!and Message Passing Interface (MPI) parallelization.                                                                              !
!                                                                                                                                  !
!Copyright (C) 2012                                                                                                                !
!Ronglin Jiang                                                                                                                     !
!rljiang@ssc.net.cn                                                                                                                !
!585 Guoshoujing Road. Pudong, Shanghai, P.R.C. 201203                                                                             !
!                                                                                                                                  !
!This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License         !
!as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.             !
!                                                                                                                                  !
!This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of    !
!MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.                        !
!                                                                                                                                  !
!You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software     !
!Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.                                                   !
!                                                                                                                                  !
!-------------------------------------------------------------LICENSE--------------------------------------------------------------!

!==================================================================================================================================|
program data_manage
!==================================================================================================================================|

   implicit none

   include 'data_manage_precision.include'
   include 'data_manage_parameter.include'

   character(4) :: ti_char, cpui_char
   character(120) :: datavis_path, var_name_list, directory
   character(256) :: header

   integer(4) :: output_method, output_level, format
   integer(4) :: ti, ci, i, j, i_s, j_s, i_e, j_e, ip1, jp1, cpui, nx_tmp, ny_tmp, i_c, i_p, j_c, j_p
   integer(4) :: id, cpu_number, ng, nx_no_bnd, nx_block, nx_total, ny_no_bnd, ny_block, ny_total, ratio, n_levels, nc
   integer(4) :: nt, n_blocks, lv, n_dims, sys, ini_block_x, ini_block_y, div_clean_flag
   integer(4) :: datamap_unit, datavis_unit
   integer(4), dimension(:), allocatable :: p_pos

   real(8) :: gm, rangex, rangey, zero_posx, zero_posy, cfl, vx, vy, vz, v2, b2, gmm1
   real(8) :: max_ro, max_mx, max_my, max_mz, max_bx, max_by, max_bz, max_en, max_az, max_v2, max_b2, max_pr, max_te, max_beta
   real(8) :: min_ro, min_mx, min_my, min_mz, min_bx, min_by, min_bz, min_en, min_az, min_v2, min_b2, min_pr, min_te, min_beta
   real(8), dimension(:), allocatable :: t, dt
   real(output_real8_flag), dimension(:, :), allocatable :: ro_base, mx_base, my_base, mz_base,                                    &
      bx_base, by_base, bz_base, en_base, pr_base, az_base
   real(output_real8_flag), dimension(:, :), allocatable :: ro, mx, my, mz, bx, by, bz, en, pr, az
   real(output_real8_flag), dimension(:, :), allocatable :: roh, mxh, myh, mzh, bxh, byh, bzh, enh, prh, azh

   real(8) :: dx, dy, eps
   real(8), dimension(:), allocatable :: x, y, xh, yh, x_base, y_base

   namelist /datavis_options/                                                                                                      &
      output_method,                                                                                                               &
      output_level,                                                                                                                &
      datavis_path,                                                                                                                &
      var_name_list,                                                                                                               &
      format,                                                                                                                      &
      header

!----------------------------------------------------------------------------------------------------------------------------------|
!  start
!----------------------------------------------------------------------------------------------------------------------------------|
   write(*, *) 
   write(*, '(a)') '|------------------|'
   write(*, '(a)') ' Data manage starts:'
   write(*, '(a)') '|------------------|'
   write(*, *)

!----------------------------------------------------------------------------------------------------------------------------------|
!  read parameters
!----------------------------------------------------------------------------------------------------------------------------------|
   eps = 1.0d-12

   open (datamap_unit, file = trim(parameters_filename))
   read (datamap_unit, nml = datavis_options)
   close (datamap_unit)

   call system("mkdir -p " // trim(datavis_path))

   datamap_unit = 10
   datavis_unit = 11
   open (datamap_unit, file = trim(datamap_path) // 'params.mapout')
   read (datamap_unit, '(a)') directory
   read (datamap_unit, *) cpu_number
   read (datamap_unit, *) n_dims
   read (datamap_unit, *) sys
   read (datamap_unit, *) ng
   read (datamap_unit, *) ini_block_x
   read (datamap_unit, *) ini_block_y
   read (datamap_unit, *) nx_no_bnd
   read (datamap_unit, *) nx_block
   read (datamap_unit, *) nx_total
   read (datamap_unit, *) ny_no_bnd
   read (datamap_unit, *) ny_block
   read (datamap_unit, *) ny_total
   read (datamap_unit, *) ratio
   read (datamap_unit, *) n_levels
   read (datamap_unit, *) div_clean_flag
   read (datamap_unit, *) gm
   read (datamap_unit, *) rangex
   read (datamap_unit, *) rangey
   read (datamap_unit, *) zero_posx
   read (datamap_unit, *) zero_posy
   read (datamap_unit, *) cfl
   close (datamap_unit)
   
   write(*,*)
   write(*,*) 'Data space:  ', trim(directory) // trim(datavis_path)
   write(*,*)
   write(*,"(a15,i5)") ' x grid points=', (nx_total - ng * 2)
   write(*,"(a15,i5)") ' y grid points=', (ny_total - ng * 2)
   write(*,*)
   
!----------------------------------------------------------------------------------------------------------------------------------|
!  read data
!----------------------------------------------------------------------------------------------------------------------------------|
   open (datamap_unit, file = trim(datamap_path) // 'nt.mapout', form = 'unformatted')
   read (datamap_unit) nt
   close (datamap_unit)

   allocate (t(nt), dt(nt), p_pos(n_dims), x(nx_block), y(ny_block), xh(nx_block), yh(ny_block),                                   &
      x_base(nx_total), y_base(ny_total),                                                                                          &
      ro(nx_block, ny_block), mx(nx_block, ny_block), my(nx_block, ny_block), mz(nx_block, ny_block),                              &
      bx(nx_block, ny_block), by(nx_block, ny_block), bz(nx_block, ny_block), en(nx_block, ny_block),                              &
      pr(nx_block, ny_block), az(nx_block, ny_block),                                                                              &
      roh(nx_block, ny_block), mxh(nx_block, ny_block), myh(nx_block, ny_block), mzh(nx_block, ny_block),                          &
      bxh(nx_block, ny_block), byh(nx_block, ny_block), bzh(nx_block, ny_block), enh(nx_block, ny_block),                          &
      prh(nx_block, ny_block), azh(nx_block, ny_block),                                                                            &
      ro_base(nx_total, ny_total), mx_base(nx_total, ny_total), my_base(nx_total, ny_total), mz_base(nx_total, ny_total),          &
      bx_base(nx_total, ny_total), by_base(nx_total, ny_total), bz_base(nx_total, ny_total), en_base(nx_total, ny_total),          &
      pr_base(nx_total, ny_total), az_base(nx_total, ny_total))

!----------------------------------------------------------------------------------------------------------------------------------|
   min_ro = 1.d10
   max_ro = -1.d10
   min_mx = 1.d10
   max_mx = -1.d10
   min_my = 1.d10
   max_my = -1.d10
   min_mz = 1.d10
   max_mz = -1.d10
   min_bx = 1.d10
   max_bx = -1.d10
   min_by = 1.d10
   max_by = -1.d10
   min_bz = 1.d10
   max_bz = -1.d10
   min_en = 1.d10
   max_en = -1.d10
   min_az = 1.d10
   max_az = -1.d10
   min_v2 = 1.d10
   max_v2 = -1.d10
   min_b2 = 1.d10
   max_b2 = -1.d10
   min_pr = 1.d10
   max_pr = -1.d10
   min_te = 1.d10
   max_te = -1.d10
   min_beta = 1.d10
   max_beta = -1.d10

   gmm1 = gm - 1.0d0

   open (datavis_unit + 0, file = trim (datavis_path) // 'tre.block.dac', form = 'unformatted')
   open (datavis_unit + 1, file = trim (datavis_path) // 'tre.x.dac', form = 'unformatted')
   open (datavis_unit + 2, file = trim (datavis_path) // 'tre.y.dac', form = 'unformatted')
   open (datavis_unit + 3, file = trim (datavis_path) // 'tre.ro.dac', form = 'unformatted')
   open (datavis_unit + 4, file = trim (datavis_path) // 'tre.mx.dac', form = 'unformatted')
   open (datavis_unit + 5, file = trim (datavis_path) // 'tre.my.dac', form = 'unformatted')
   open (datavis_unit + 6, file = trim (datavis_path) // 'tre.mz.dac', form = 'unformatted')
   open (datavis_unit + 7, file = trim (datavis_path) // 'tre.bx.dac', form = 'unformatted')
   open (datavis_unit + 8, file = trim (datavis_path) // 'tre.by.dac', form = 'unformatted')
   open (datavis_unit + 9, file = trim (datavis_path) // 'tre.bz.dac', form = 'unformatted')
   open (datavis_unit + 10, file = trim (datavis_path) // 'tre.en.dac', form = 'unformatted')
   open (datavis_unit + 11, file = trim (datavis_path) // 'tre.az.dac', form = 'unformatted')

   do ti = 1, nt

      write (ti_char, '(i4.4)') ti

!----------------------------------------------------------------------------------------------------------------------------------|
!     read t, dt
!----------------------------------------------------------------------------------------------------------------------------------|
      open (datamap_unit, file = trim(datamap_path) // 'info.t' // ti_char // '.mapout', form = 'unformatted')
      read (datamap_unit) t(ti)
      read (datamap_unit) dt(ti)
      close (datamap_unit)

      write (*, *) ' Time = ', t(ti)

      do cpui = 0, cpu_number - 1
!----------------------------------------------------------------------------------------------------------------------------------|
!        read n_blocks
!----------------------------------------------------------------------------------------------------------------------------------|
         write (cpui_char, '(i4.4)') cpui

         open (datamap_unit, file = trim(datamap_path) // 'data.t' // ti_char // '.cpu' // cpui_char // '.mapout',                 &
            form = 'unformatted')
         read (datamap_unit) n_blocks
         write (datavis_unit + 0) n_blocks

         do ci = 1, n_blocks
!----------------------------------------------------------------------------------------------------------------------------------|
!           read x, ro, mx, my, mz, bx, by, bz, en
!----------------------------------------------------------------------------------------------------------------------------------|
            read (datamap_unit) id
            read (datamap_unit) lv, nc, p_pos
            read (datamap_unit) dx
            read (datamap_unit) dy

            read (datamap_unit) x
            read (datamap_unit) y
            read (datamap_unit) ro
            read (datamap_unit) mx
            read (datamap_unit) my
            read (datamap_unit) mz
            read (datamap_unit) bx
            read (datamap_unit) by
            read (datamap_unit) bz
            read (datamap_unit) en
            read (datamap_unit) az

            i_e = nx_block - 1
            j_e = ny_block - 1

            pr = (en - (mx ** 2 + my ** 2 + mz ** 2) / ro / 2.0d0 - (bx ** 2 + by ** 2 + bz ** 2) / 2.0d0) * gmm1

            do i = 1, i_e
               xh(i) = (x(i) + x(i + 1)) / 2.0d0
            enddo

            do j = 1, j_e
               yh(j) = (y(j) + y(j + 1)) / 2.0d0
            enddo

            do j = 1, j_e
               jp1 = j + 1
               do i = 1, i_e
                  ip1 = i + 1
                  roh(i, j) = (ro(i, j) + ro(ip1, j) + ro(i, jp1) + ro(ip1, jp1)) / 4.0d0
                  mxh(i, j) = (mx(i, j) + mx(ip1, j) + mx(i, jp1) + mx(ip1, jp1)) / 4.0d0
                  myh(i, j) = (my(i, j) + my(ip1, j) + my(i, jp1) + my(ip1, jp1)) / 4.0d0
                  mzh(i, j) = (mz(i, j) + mz(ip1, j) + mz(i, jp1) + mz(ip1, jp1)) / 4.0d0
                  bxh(i, j) = (bx(i, j) + bx(ip1, j) + bx(i, jp1) + bx(ip1, jp1)) / 4.0d0
                  byh(i, j) = (by(i, j) + by(ip1, j) + by(i, jp1) + by(ip1, jp1)) / 4.0d0
                  bzh(i, j) = (bz(i, j) + bz(ip1, j) + bz(i, jp1) + bz(ip1, jp1)) / 4.0d0
                  prh(i, j) = (pr(i, j) + pr(ip1, j) + pr(i, jp1) + pr(ip1, jp1)) / 4.0d0
                  azh(i, j) = (az(i, j) + az(ip1, j) + az(i, jp1) + az(ip1, jp1)) / 4.0d0
               enddo
            enddo

            if (lv .eq. 1) then
               nx_tmp = (p_pos(1) - 1) * nx_no_bnd + ng
               ny_tmp = (p_pos(2) - 1) * ny_no_bnd + ng

               do i = 0, nx_no_bnd
                  i_c = i + ng
                  i_p = i + nx_tmp
                  x_base(i_p) = xh(i_c)
               enddo

               do j = 0, ny_no_bnd
                  j_c = j + ng
                  j_p = j + ny_tmp
                  y_base(j_p) = yh(j_c)
               enddo

               do j = 0, ny_no_bnd
                  j_c = j + ng
                  j_p = j + ny_tmp
                  do i = 0, nx_no_bnd
                     i_c = i + ng
                     i_p = i + nx_tmp
                     ro_base(i_p, j_p) = roh(i_c, j_c)
                     mx_base(i_p, j_p) = mxh(i_c, j_c)
                     my_base(i_p, j_p) = myh(i_c, j_c)
                     mz_base(i_p, j_p) = mzh(i_c, j_c)
                     bx_base(i_p, j_p) = bxh(i_c, j_c)
                     by_base(i_p, j_p) = byh(i_c, j_c)
                     bz_base(i_p, j_p) = bzh(i_c, j_c)
                     pr_base(i_p, j_p) = prh(i_c, j_c)
                     az_base(i_p, j_p) = azh(i_c, j_c)
                  enddo
               enddo
            endif

            enh = (mxh ** 2 + myh ** 2 + mzh ** 2) / roh / 2.0d0 + (bxh ** 2 + byh ** 2 + bzh ** 2) / 2.0d0 + prh / gmm1

            write (datavis_unit + 0) lv, nc, dx, dy
            write (datavis_unit + 1) xh(ng : nx_block - ng)
            write (datavis_unit + 2) yh(ng : ny_block - ng)
            write (datavis_unit + 3) roh(ng : nx_block - ng, ng : ny_block - ng)
            write (datavis_unit + 4) mxh(ng : nx_block - ng, ng : ny_block - ng)
            write (datavis_unit + 5) myh(ng : nx_block - ng, ng : ny_block - ng)
            write (datavis_unit + 6) mzh(ng : nx_block - ng, ng : ny_block - ng)
            write (datavis_unit + 7) bxh(ng : nx_block - ng, ng : ny_block - ng)
            write (datavis_unit + 8) byh(ng : nx_block - ng, ng : ny_block - ng)
            write (datavis_unit + 9) bzh(ng : nx_block - ng, ng : ny_block - ng)
            write (datavis_unit + 10) enh(ng : nx_block - ng, ng : ny_block - ng)
            write (datavis_unit + 11) azh(ng : nx_block - ng, ng : ny_block - ng)

            i_s = ng + 1
            i_e = nx_block - ng
            j_s = ng + 1
            j_e = ny_block - ng

            do j = j_s, j_e
            do i = i_s, i_e
               min_ro = min (min_ro, ro(i, j))
               max_ro = max (max_ro, ro(i, j))
               min_mx = min (min_mx, mx(i, j))
               max_mx = max (max_mx, mx(i, j))
               min_my = min (min_my, my(i, j))
               max_my = max (max_my, my(i, j))
               min_mz = min (min_mz, mz(i, j))
               max_mz = max (max_mz, mz(i, j))
               min_bx = min (min_bx, bx(i, j))
               max_bx = max (max_bx, bx(i, j))
               min_by = min (min_by, by(i, j))
               max_by = max (max_by, by(i, j))
               min_bz = min (min_bz, bz(i, j))
               max_bz = max (max_bz, bz(i, j))
               min_en = min (min_en, en(i, j))
               max_en = max (max_en, en(i, j))
               min_az = min (min_az, az(i, j))
               max_az = max (max_az, az(i, j))
               vx = mx(i, j) / ro(i, j)
               vy = my(i, j) / ro(i, j)
               vz = mz(i, j) / ro(i, j)
               v2 = vx ** 2 + vy ** 2 + vz ** 2
               b2 = bx(i, j) ** 2 + by(i, j) ** 2 + bz(i, j) ** 2
               min_v2 = min (min_v2, v2)
               max_v2 = max (max_v2, v2)
               min_b2 = min (min_b2, b2)
               max_b2 = max (max_b2, b2)
               min_pr = min (min_pr, pr(i, j))
               max_pr = max (max_pr, pr(i, j))
               min_te = min (min_te, pr(i, j) / ro(i, j))
               max_te = max (max_te, pr(i, j) / ro(i, j))
               min_beta = min (min_beta, pr(i, j) / b2 * 2.0d0)
               max_beta = max (max_beta, pr(i, j) / b2 * 2.0d0)
            enddo
            enddo

         enddo
      enddo

      en_base = (mx_base ** 2 + my_base ** 2 + mz_base ** 2) / ro_base / 2.0d0 +                                                   &
         (bx_base ** 2 + by_base ** 2 + bz_base ** 2) / 2.0d0 + pr_base / (gm - 1.0d0)

      write (datavis_unit + 0) lv, nc, dx, dy
      write (datavis_unit + 1) x_base(ng : nx_total - ng)
      write (datavis_unit + 2) y_base(ng : ny_total - ng)
      write (datavis_unit + 3) ro_base(ng : nx_total - ng, ng : ny_total - ng)
      write (datavis_unit + 4) mx_base(ng : nx_total - ng, ng : ny_total - ng)
      write (datavis_unit + 5) my_base(ng : nx_total - ng, ng : ny_total - ng)
      write (datavis_unit + 6) mz_base(ng : nx_total - ng, ng : ny_total - ng)
      write (datavis_unit + 7) bx_base(ng : nx_total - ng, ng : ny_total - ng)
      write (datavis_unit + 8) by_base(ng : nx_total - ng, ng : ny_total - ng)
      write (datavis_unit + 9) bz_base(ng : nx_total - ng, ng : ny_total - ng)
      write (datavis_unit + 10) en_base(ng : nx_total - ng, ng : ny_total - ng)
      write (datavis_unit + 11) az_base(ng : nx_total - ng, ng : ny_total - ng)

   enddo

   close (datavis_unit + 0)
   close (datavis_unit + 1)
   close (datavis_unit + 2)
   close (datavis_unit + 3)
   close (datavis_unit + 4)
   close (datavis_unit + 5)
   close (datavis_unit + 6)
   close (datavis_unit + 7)
   close (datavis_unit + 8)
   close (datavis_unit + 9)
   close (datavis_unit + 10)
   close (datavis_unit + 11)

!----------------------------------------------------------------------------------------------------------------------------------|
!   write time
!----------------------------------------------------------------------------------------------------------------------------------|
   open (datavis_unit, file = trim(datavis_path) // 'tre.t.dac', form = 'unformatted')
   write (datavis_unit) nt
   write (datavis_unit) t
   write (datavis_unit) dt
   close (datavis_unit)

!----------------------------------------------------------------------------------------------------------------------------------|
!   write parameters
!----------------------------------------------------------------------------------------------------------------------------------|
   open (datavis_unit, file = trim(datavis_path) // 'tre.par.dac')
   write (datavis_unit, '(a)') 'work space: ' // trim(directory)
   write (datavis_unit, '(i5, t64, a)') cpu_number, 'cpu_number'
   write (datavis_unit, '(i5, t64, a)') n_dims, 'n_dims'
   write (datavis_unit, '(i5, t64, a)') sys, 'sys'
   write (datavis_unit, '(i5, t64, a)') ng, 'ng'
   write (datavis_unit, '(i5, t64, a)') ini_block_x, 'ini_block_x'
   write (datavis_unit, '(i5, t64, a)') ini_block_y, 'ini_block_y'
   write (datavis_unit, '(i5, t64, a)') nx_no_bnd, 'nx_no_bnd'
   write (datavis_unit, '(i5, t64, a)') nx_block, 'nx_block'
   write (datavis_unit, '(i5, t64, a)') nx_total, 'nx_total'
   write (datavis_unit, '(i5, t64, a)') ny_no_bnd, 'ny_no_bnd'
   write (datavis_unit, '(i5, t64, a)') ny_block, 'ny_block'
   write (datavis_unit, '(i5, t64, a)') ny_total, 'ny_total'
   write (datavis_unit, '(i5, t64, a)') ratio, 'ratio'
   write (datavis_unit, '(i5, t64, a)') n_levels, 'n_levels'
   write (datavis_unit, '(i5, t64, a)') div_clean_flag, 'div_clean_flag'
   write (datavis_unit, '(i5, t64, a)') output_real8_flag, 'output_real8_flag'
   write (datavis_unit, '(e15.6, t64, a)') gm, 'gm'
   write (datavis_unit, '(e15.6, t64, a)') rangex, 'rangex'
   write (datavis_unit, '(e15.6, t64, a)') rangey, 'rangey'
   write (datavis_unit, '(e15.6, t64, a)') zero_posx, 'zero_posx'
   write (datavis_unit, '(e15.6, t64, a)') zero_posy, 'zero_posy'
   write (datavis_unit, '(e15.6, t64, a)') cfl, 'cfl'
   write (datavis_unit, '(e15.6, t64, a)') min_ro, 'min ro'
   write (datavis_unit, '(e15.6, t64, a)') max_ro, 'max ro'
   write (datavis_unit, '(e15.6, t64, a)') min_mx, 'min mx'
   write (datavis_unit, '(e15.6, t64, a)') max_mx, 'max mx'
   write (datavis_unit, '(e15.6, t64, a)') min_my, 'min my'
   write (datavis_unit, '(e15.6, t64, a)') max_my, 'max my'
   write (datavis_unit, '(e15.6, t64, a)') min_mz, 'min mz'
   write (datavis_unit, '(e15.6, t64, a)') max_mz, 'max mz'
   write (datavis_unit, '(e15.6, t64, a)') min_bx, 'min bx'
   write (datavis_unit, '(e15.6, t64, a)') max_bx, 'max bx'
   write (datavis_unit, '(e15.6, t64, a)') min_by, 'min by'
   write (datavis_unit, '(e15.6, t64, a)') max_by, 'max by'
   write (datavis_unit, '(e15.6, t64, a)') min_bz, 'min bz'
   write (datavis_unit, '(e15.6, t64, a)') max_bz, 'max bz'
   write (datavis_unit, '(e15.6, t64, a)') min_en, 'min en'
   write (datavis_unit, '(e15.6, t64, a)') max_en, 'max en'
   write (datavis_unit, '(e15.6, t64, a)') min_az, 'min az'
   write (datavis_unit, '(e15.6, t64, a)') max_az, 'max az'
   write (datavis_unit, '(e15.6, t64, a)') min_v2, 'min v2'
   write (datavis_unit, '(e15.6, t64, a)') max_v2, 'max v2'
   write (datavis_unit, '(e15.6, t64, a)') min_b2, 'min b2'
   write (datavis_unit, '(e15.6, t64, a)') max_b2, 'max b2'
   write (datavis_unit, '(e15.6, t64, a)') min_pr, 'min pr'
   write (datavis_unit, '(e15.6, t64, a)') max_pr, 'max pr'
   write (datavis_unit, '(e15.6, t64, a)') min_te, 'min te'
   write (datavis_unit, '(e15.6, t64, a)') max_te, 'max te'
   write (datavis_unit, '(e15.6, t64, a)') min_beta, 'min beta'
   write (datavis_unit, '(e15.6, t64, a)') max_beta, 'max beta'
   close (datavis_unit)

   deallocate (t, dt, p_pos, x, y, ro, mx, my, mz, bx, by, bz, en, pr, az,                                                         &
      xh, yh, roh, mxh, myh, mzh, bxh, byh, bzh, enh, prh, azh,                                                                    &
      x_base, y_base, ro_base, mx_base, my_base, mz_base, bx_base, by_base, bz_base, en_base, pr_base, az_base)

   write (*,*)
   write (*,*) ' Read data complete!'
   write (*,*)
   
!----------------------------------------------------------------------------------------------------------------------------------|
   stop
end program data_manage
